package com.minsu.config;

import com.minsu.entity.SysUser;
import com.minsu.service.SysUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import javax.sql.DataSource;

@Configuration
@EnableWebSecurity
public class  SecurityConfig extends WebSecurityConfigurerAdapter {

    private final SysUserService userService;
    private final DataSource dataSource;

    public SecurityConfig(SysUserService userService, DataSource dataSource) {
        this.userService = userService;
        this.dataSource = dataSource;
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 警告：仅用于开发测试，生产环境请使用 BCryptPasswordEncoder
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        // 首次启动时创建表，后续注释掉
        // tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return username -> {
            SysUser user = userService.findByUsername(username);
            if (user == null) {
                throw new UsernameNotFoundException("用户不存在");
            }
            return org.springframework.security.core.userdetails.User
                    .withUsername(username)
                    .password(user.getPassword())
                    .roles("USER")
                    .build();
        };
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 开发环境下允许所有请求，不需要认证
        http
            .authorizeRequests()
                .antMatchers("/css/**", "/js/**", "/images/**", "/webjars/**").permitAll()
            //     .antMatchers("/login", "/error", "/api/login").permitAll()
            //     .anyRequest().authenticated()
            // .and()
            // .formLogin()
            //     .loginPage("/login")
            //     .defaultSuccessUrl("/", true)
            //     .failureUrl("/login?error")
            //     .permitAll()
            // .and()
            // .rememberMe()
            //     .tokenRepository(persistentTokenRepository())
            //     .tokenValiditySeconds(60 * 60 * 24 * 7) // 7天
            //     .userDetailsService(userDetailsService())
            // .and()
            // .logout()
            //     .logoutUrl("/logout")
            //     .logoutSuccessUrl("/login?logout")
            //     .deleteCookies("JSESSIONID")
            //     .clearAuthentication(true)
            //     .invalidateHttpSession(true)
            //     .permitAll()
                .anyRequest().permitAll()
            .and()
            .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
            .passwordEncoder(passwordEncoder());
    }
} 